home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / src / ax25.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-26  |  9.6 KB  |  419 lines

  1. /* @(#) $Header: ax25.c,v 1.10 91/04/25 18:26:34 deyke Exp $ */
  2.  
  3. /* Low level AX.25 code:
  4.  *  incoming frame processing (including digipeating)
  5.  *  IP encapsulation
  6.  *  digipeater routing
  7.  *
  8.  * Copyright 1991 Phil Karn, KA9Q
  9.  */
  10. #include <stdio.h>
  11. #include "global.h"
  12. #include "mbuf.h"
  13. #include "iface.h"
  14. #include "arp.h"
  15. #include "slip.h"
  16. #include "ax25.h"
  17. #include "lapb.h"
  18. #include "netrom.h"
  19. #include "ip.h"
  20. #include <ctype.h>
  21.  
  22. static int axsend __ARGS((struct iface *iface,char *dest,char *source,
  23.     int cmdrsp,int ctl,struct mbuf *data));
  24. static int axroute_hash __ARGS((char *call));
  25.  
  26. /* AX.25 broadcast address: "QST-0" in shifted ascii */
  27. char Ax25_bdcst[AXALEN] = {
  28.     'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1,
  29. };
  30. char Mycall[AXALEN];
  31. struct ax_route *Ax_routes[AXROUTESIZE];
  32. struct iface *axroute_default_ifp;
  33. int Digipeat = 2;       /* Controls digipeating */
  34.  
  35. /* Send IP datagrams across an AX.25 link */
  36. int
  37. ax_send(bp,iface,gateway,prec,del,tput,rel)
  38. struct mbuf *bp;
  39. struct iface *iface;
  40. int32 gateway;
  41. int prec;
  42. int del;
  43. int tput;
  44. int rel;
  45. {
  46.     char *hw_addr;
  47.  
  48.     if((hw_addr = res_arp(iface,ARP_AX25,gateway,bp)) == NULLCHAR)
  49.         return 0;       /* Wait for address resolution */
  50.  
  51.         /* Use UI frame */
  52.         return (*iface->output)(iface,hw_addr,iface->hwaddr,PID_IP,bp);
  53.  
  54. }
  55. /* Add header and send connectionless (UI) AX.25 packet.
  56.  * Note that the calling order here must match enet_output
  57.  * since ARP also uses it.
  58.  */
  59. int
  60. ax_output(iface,dest,source,pid,data)
  61. struct iface *iface;    /* Interface to use; overrides routing table */
  62. char *dest;             /* Destination AX.25 address (7 bytes, shifted) */
  63. char *source;           /* Source AX.25 address (7 bytes, shifted) */
  64. int16 pid;              /* Protocol ID */
  65. struct mbuf *data;      /* Data field (follows PID) */
  66. {
  67.     struct mbuf *bp;
  68.  
  69.     /* Prepend pid to data */
  70.     bp = pushdown(data,1);
  71.     if(bp == NULLBUF){
  72.         free_p(data);
  73.         return -1;
  74.     }
  75.     bp->data[0] = (char)pid;
  76.     return axsend(iface,dest,source,LAPB_COMMAND,UI,bp);
  77. }
  78. /* Common subroutine for sendframe() and ax_output() */
  79. static int
  80. axsend(iface,dest,source,cmdrsp,ctl,data)
  81. struct iface *iface;    /* Interface to use; overrides routing table */
  82. char *dest;             /* Destination AX.25 address (7 bytes, shifted) */
  83. char *source;           /* Source AX.25 address (7 bytes, shifted) */
  84. int cmdrsp;             /* Command/response indication */
  85. int ctl;                /* Control field */
  86. struct mbuf *data;      /* Data field (includes PID) */
  87. {
  88.     struct mbuf *cbp;
  89.     struct ax25 addr;
  90.     struct ax_route *dp,*rp;
  91.     int rval;
  92.     int i;
  93.  
  94.     /* If the source addr is unspecified, use the interface address */
  95.     if(source[0] == '\0')
  96.         source = iface->hwaddr;
  97.  
  98.     memcpy(addr.dest,dest,AXALEN);
  99.     memcpy(addr.source,source,AXALEN);
  100.     addr.cmdrsp = cmdrsp;
  101.  
  102.     addr.ndigis = 0;
  103.     /* If there's a digipeater route, get it */
  104.     if (rp = ax_routeptr(dest, 0)) {
  105.         for (dp = rp->digi; dp; dp = dp->digi)
  106.             addr.ndigis++;
  107.         i = addr.ndigis;
  108.         for (dp = rp->digi; dp; dp = dp->digi) {
  109.             i--;
  110.             if (i < MAXDIGIS)
  111.                 addrcp(addr.digis[i], dp->call);
  112.         }
  113.     }
  114.  
  115.     addr.nextdigi = 0;
  116.  
  117.     /* Allocate mbuf for control field, and fill in */
  118.     if((cbp = pushdown(data,1)) == NULLBUF){
  119.         free_p(data);
  120.         return -1;
  121.     }
  122.     cbp->data[0] = ctl;
  123.  
  124.     if((data = htonax25(&addr,cbp)) == NULLBUF){
  125.         free_p(cbp);    /* Also frees data */
  126.         return -1;
  127.     }
  128.     /* This shouldn't be necessary because redirection has already been
  129.      * done at the IP router layer, but just to be safe...
  130.      */
  131.     if(iface->forw != NULLIF){
  132.         rval = (*iface->forw->raw)(iface->forw,data);
  133.     } else {
  134.         rval = (*iface->raw)(iface,data);
  135.     }
  136.     return rval;
  137. }
  138.  
  139. /* Process incoming AX.25 packets.
  140.  * After optional tracing, the address field is examined. If it is
  141.  * directed to us as a digipeater, repeat it.  If it is addressed to
  142.  * us or to QST-0, kick it upstairs depending on the protocol ID.
  143.  */
  144. void
  145. ax_recv(iface,bp)
  146. struct iface *iface;
  147. struct mbuf *bp;
  148. {
  149.     struct mbuf *hbp;
  150.     char control;
  151.     struct ax25 hdr;
  152.     char **mpp;
  153.     int mcast;
  154.  
  155.     /* Pull header off packet and convert to host structure */
  156.     if(ntohax25(&hdr,&bp) < 0){
  157.         /* Something wrong with the header */
  158.         free_p(bp);
  159.         return;
  160.     }
  161.     /* If there were digis in this packet, then the last digi was the
  162.      * actual transmitter. Otherwise the source is the transmitter.
  163.      */
  164.  
  165.     if(hdr.nextdigi < hdr.ndigis){
  166.         /* Packet hasn't passed all digipeaters yet. See if
  167.          * we have to repeat it.
  168.          */
  169.         if(Digipeat && addreq(hdr.digis[hdr.nextdigi],iface->hwaddr)){
  170.             /* Yes, kick it back out. htonax25 will set the
  171.              * repeated bit.
  172.              */
  173.             axroute_add(iface, &hdr, 0);
  174.             hdr.nextdigi++;
  175.             switch(Digipeat){
  176.             case 1:
  177.                 if((hbp = htonax25(&hdr,bp)) != NULLBUF){
  178.                     axroute(NULL,hbp);
  179.                     bp = NULLBUF;
  180.                 }
  181.                 break;
  182.             case 2:
  183.                 lapb_input(iface,&hdr,bp);
  184.                 bp = NULLBUF;
  185.                 break;
  186.             }
  187.         }
  188.         free_p(bp);     /* Dispose if not forwarded */
  189.         return;
  190.     }
  191.     /* If we reach this point, then the packet has passed all digis,
  192.      * but it is not necessarily for us.
  193.      */
  194.     if(bp == NULLBUF){
  195.         /* Nothing left */
  196.         return;
  197.     }
  198.     /* Examine destination to see if it's either addressed to us or
  199.      * a multicast.
  200.      */
  201.     mcast = 0;
  202.     for(mpp = Axmulti;*mpp != NULLCHAR;mpp++){
  203.         if(addreq(hdr.dest,*mpp)){
  204.             mcast = 1;
  205.             break;
  206.         }
  207.     }
  208.     if(!mcast && !addreq(hdr.dest,iface->hwaddr)){
  209.         /* Not a broadcast, and not addressed to us; ignore */
  210.         free_p(bp);
  211.         return;
  212.     }
  213.  
  214.     if(!mcast)
  215.         axroute_add(iface, &hdr, 0);
  216.  
  217.     /* Sneak a peek at the control field. This kludge is necessary because
  218.      * AX.25 lacks a proper protocol ID field between the address and LAPB
  219.      * sublayers; a control value of UI indicates that LAPB is to be
  220.      * bypassed.
  221.      */
  222.     control = *bp->data & ~PF;
  223.  
  224.     if(uchar(control) == UI){
  225.         int pid;
  226.         struct axlink *ipp;
  227.  
  228.         (void) PULLCHAR(&bp);
  229.         if((pid = PULLCHAR(&bp)) == -1)
  230.             return;         /* No PID */
  231.         /* Find network level protocol and hand it off */
  232.         for(ipp = Axlink;ipp->funct        ;ipp++){
  233.             if(ipp->pid == pid)
  234.                 break;
  235.         }
  236.         if(ipp->funct        )
  237.             (*ipp->funct)(iface,(void *) 0,hdr.source,hdr.dest,bp,mcast);
  238.         else
  239.             free_p(bp);
  240.         return;
  241.     }
  242.     /* Everything from here down is connected-mode LAPB, so ignore
  243.      * multicasts
  244.      */
  245.     if(mcast){
  246.         free_p(bp);
  247.         return;
  248.     }
  249.  
  250.     lapb_input(iface,&hdr,bp);
  251. }
  252.  
  253. /*---------------------------------------------------------------------------*/
  254.  
  255. static int  axroute_hash(call)
  256. char  *call;
  257. {
  258.   long  hashval;
  259.  
  260.   hashval  = ((*call++ << 23) & 0x0f000000);
  261.   hashval |= ((*call++ << 19) & 0x00f00000);
  262.   hashval |= ((*call++ << 15) & 0x000f0000);
  263.   hashval |= ((*call++ << 11) & 0x0000f000);
  264.   hashval |= ((*call++ <<  7) & 0x00000f00);
  265.   hashval |= ((*call++ <<  3) & 0x000000f0);
  266.   hashval |= ((*call   >>  1) & 0x0000000f);
  267.   return hashval % AXROUTESIZE;
  268. }
  269.  
  270. /*---------------------------------------------------------------------------*/
  271.  
  272. struct ax_route *ax_routeptr(call, create)
  273. char  *call;
  274. int  create;
  275. {
  276.  
  277.   int  hashval;
  278.   struct ax_route *rp;
  279.  
  280.   hashval = axroute_hash(call);
  281.   for (rp = Ax_routes[hashval]; rp && !addreq(rp->call, call); rp = rp->next) ;
  282.   if (!rp && create) {
  283.     rp = (struct ax_route *) calloc(1, sizeof(struct ax_route ));
  284.     addrcp(rp->call, call);
  285.     rp->next = Ax_routes[hashval];
  286.     Ax_routes[hashval] = rp;
  287.   }
  288.   return rp;
  289. }
  290.  
  291. /*---------------------------------------------------------------------------*/
  292.  
  293. void axroute_add(iface, hdr, perm)
  294. struct iface *iface;
  295. struct ax25 *hdr;
  296. int  perm;
  297. {
  298.  
  299.   char  **mpp;
  300.   char  *call;
  301.   char  *calls[MAXDIGIS+1];
  302.   int  i;
  303.   int  j;
  304.   int  ncalls = 0;
  305.   struct ax_route *lastnode = 0;
  306.   struct ax_route *rp;
  307.  
  308.   call = hdr->source;
  309.   if (!*call || addreq(call, iface->hwaddr)) return;
  310.   for (mpp = Axmulti; *mpp; mpp++)
  311.     if (addreq(call, *mpp)) return;
  312.   calls[ncalls++] = call;
  313.   for (i = 0; i < hdr->nextdigi; i++) {
  314.     call = hdr->digis[i];
  315.     if (!*call || addreq(call, iface->hwaddr)) return;
  316.     for (mpp = Axmulti; *mpp; mpp++)
  317.       if (addreq(call, *mpp)) return;
  318.     for (j = 0; j < ncalls; j++)
  319.       if (addreq(call, calls[j])) return;
  320.     calls[ncalls++] = call;
  321.   }
  322.  
  323.   for (i = ncalls - 1; i >= 0; i--) {
  324.     rp = ax_routeptr(calls[i], 1);
  325.     if (perm || !rp->perm) {
  326.       if (lastnode) {
  327.     rp->digi = lastnode;
  328.     rp->ifp = 0;
  329.       } else {
  330.     rp->digi = 0;
  331.     rp->ifp = iface;
  332.       }
  333.       rp->perm = perm;
  334.     }
  335.     rp->time = secclock();
  336.     lastnode = rp;
  337.   }
  338.   axroute_savefile();
  339. }
  340.  
  341. /*---------------------------------------------------------------------------*/
  342.  
  343. void axroute(cp, bp)
  344. struct ax25_cb *cp;
  345. struct mbuf *bp;
  346. {
  347.  
  348.   char  *dest;
  349.   struct ax_route *rp;
  350.   struct iface *ifp;
  351.  
  352.   if (cp && cp->ifp)
  353.     ifp = cp->ifp;
  354.   else {
  355.     if (bp->data[AXALEN + 6] & E)
  356.       dest = bp->data;
  357.     else
  358.       for (dest = bp->data + 2 * AXALEN; ; dest += AXALEN) {
  359.     if (!(dest[6] & REPEATED)) break;
  360.     if (dest[6] & E) {
  361.       dest = bp->data;
  362.       break;
  363.     }
  364.       }
  365.     rp = ax_routeptr(dest, 0);
  366.     ifp = (rp && rp->ifp) ? rp->ifp : axroute_default_ifp;
  367.   }
  368.   if (ifp) {
  369.     if (ifp->forw) ifp = ifp->forw;
  370.     (*ifp->raw)(ifp, bp);
  371.   } else
  372.     free_p(bp);
  373. }
  374.  
  375. /*---------------------------------------------------------------------------*/
  376.  
  377. /* Handle ordinary incoming data (no network protocol) */
  378. void
  379. axnl3(iface,axp,src,dest,bp,mcast)
  380. struct iface *iface;
  381. struct ax25_cb *axp;
  382. char *src;
  383. char *dest;
  384. struct mbuf *bp;
  385. int mcast;
  386. {
  387.     free_p(bp);
  388. }
  389.  
  390. /*---------------------------------------------------------------------------*/
  391.  
  392. char  *ax25hdr_to_string(hdr)
  393. struct ax25 *hdr;
  394. {
  395.  
  396.   char  *p;
  397.   int  i;
  398.   static char  buf[128];
  399.  
  400.   if (!*hdr->dest) return "*";
  401.   p = buf;
  402.   if (*hdr->source) {
  403.     pax25(p, hdr->source);
  404.     while (*p) p++;
  405.     *p++ = '-';
  406.     *p++ = '>';
  407.   }
  408.   pax25(p, hdr->dest);
  409.   while (*p) p++;
  410.   for (i = 0; i < hdr->ndigis; i++) {
  411.     *p++ = ',';
  412.     pax25(p, hdr->digis[i]);
  413.     while (*p) p++;
  414.     if (i < hdr->nextdigi) *p++ = '*';
  415.   }
  416.   *p = '\0';
  417.   return buf;
  418. }
  419.